AWS ACM과 HTTPS
HTTP(HyperText Transfer Protocol) 은 웹에서 데이터를 주고받는 규약으로 문제는, 암호화가 전혀 없다 HTTP는 “텍스트 그대로” 패킷단위로 주고받는데, 누군가 중간에서 패킷을 엿보면 이런 게 다 보인다.
POST /login
username=maru&password=1234
회사 와이파이, 카페 공유기, ISP 어디서든 탈취 가능하고 위변조 가능 (MITM, Man-In-The-Middle 공격)하다. 이 문제를 해결하기 위해 “S(Secure)”가 붙은 게 HTTPS
HTTPS와 TLS/SSL은 무엇일까?
HTTPS = HTTP + TLS(SSL)
즉, HTTP 통신 위에 TLS(Transport Layer Security) 라는 암호화 계층을 덧씌운 프로토콜이다.
TLS는 공개키 암호화(PKI) 와 인증서(Certificate) 가 핵심이다.
사실 대칭키 암호화도 같이 쓰이지만, 보안 단계를 설명할 때 핵심은 공개키 암호화다
”보안 어떻게 동작하는거지?” 섹션 더 자세히 설명되어 있다.
그렇다면 SSL은 무엇일까?
간단히 말하면, TLS는 SSL의 후속 버전(진화판) 인데, 두 프로토콜 모두 HTTP를 암호화해주는 보안 계층이라는 점은 동일하지만, SSL은 사설에서 운영되던 것이고 보안 문제로 인해 이제 완전히 폐기(deprecated)되었다.
이제 기술적으로는 전부 TLS인데, 개발자나 도구에서는 여전히 “SSL”이라는 이름이 남아있다 즉, 지금의 “SSL 인증서”는 실제로는TLS 인증서다. 그냥 “역사적으로 남은 용어”일 뿐
그래서, TLS 보안은 어떻게 동작하는거지 ?
TLS가 동작하는 순서를 먼저 살펴보자
TLS Handshake
브라우저가 https://example.com 접속할 때 실제로는 이런 일이 일어난다.
아래는 TLS 1.3 기준
- ClientHello(클라이언트 → 서버) : TLS 연결하자. 랜덤값과 클라이언트용 공개키 줄게
- ServerHello(서버 → 클라이언트) : 이 알고리즘으로 하자, 랜덤값과 서버용 공개키가 담긴 인증서 줄게
- 클라이언트에서 인증서 검증
- 키 교환 : 서로의 keyshare(공개키)를 이용해 공유 비밀키 계산
- 세션 키 생성 : 공유 비밀키 + 서로의 랜덤값을 합쳐서 데이터 암호화용 대칭키(세션키) 생성
- 핸드쉐이크 종료 : Finished 메세지를 서로 교환하며 무결성 검증
- 이제 모든 HTTP 데이터는 대칭키로 암호화되어 송수신
이 일련의 과정을 TLS Handshake라고 하며,
이 핸드쉐이크를 통해 중간에 패킷이 탈취되어도 보안을 유지할 수 있게 되었다.
TLS는 왜 공개키와 대칭키 모두 사용할까 ?
먼저 공개키 암호화와 대칭키 암호화에 대해 간단히 알아보자.
공개키 암호화- 공개키(Public Key)는 서버-클라이언트간 공유되며, 비밀키(Private Key)는 공유되지 않는다.
- 데이터를 공개키로 암호화하면, 비밀키로만 복호화할 수 있다.
- 이 방식은 보안성은 높지만 연산이 느리다. 실제 데이터 전송보다는 세션키(대칭키)를 안전하게 교환하는 용도로 사용된다.
대칭키 암호화- 하나의 키로 암호화와 복호화를 모두 수행한다. 즉, 같은 키를 양쪽(서버·클라이언트)이 공유한다
- 연산이 단순하고 빠르기 때문에, 실제 HTTP 요청/응답 데이터를 암호화하는 데 사용된다
- 단점은 이 “공통 키(세션키)”를 어떻게 안전하게 공유하느냐인데, 이걸 공개키 암호화로 해결한다
즉, TLS는 두 방식을 결합해 각자의 장점을 취한다.
- 공개키 암호화로 안전하게 세션키를 교환하고,
- 대칭키 암호화로 빠르고 효율적으로 데이터를 주고받는다.
공개키 암호화는 “안전한 통신 준비”용, 대칭키 암호화는 “실제 통신 실행”용이다. TLS는 이 두 가지를 결합해 는 보안성(비밀키 노출 없이 안전한 키 교환)과 성능(빠른 암호화 통신) 을 모두 확보할 수 있다.
TLS Handshake와 3-way handshake의 차이
TCP 3-Way Handshake
L4 계층의 핸드세이크로, 패킷을 안전하게 주고받을 통로를 만드는 작업이다. TCP에서 “패킷의 신뢰성” 있는 전달을 위한 “연결 수립” 용도다.
TLS Handshake
L6 ~ L7 계층의 핸드셰이크로, 통신의 “보안”을 위해 쓰인다. 통신을 암호화할 키를 교환하고, 상대가 진짜인지 검증하는 용도다.
TLS Handshake는 매 요청마다 일어나는 게 아니라, TCP 연결이 처음 맺어질 때 한 번만 수행된다. 이후 같은 TLS 세션 위에서는 여러 HTTP 요청을 암호화된 채로 주고받을 수 있다.
개발자도구에서 평문이 보이는 이유는, 브라우저 내부에서 이미 TLS 계층이 복호화를 끝낸 뒤 애플리케이션 계층(L7)으로 올려주기 때문이다.
TLS 공개키는 어떻게 만들어지는 걸까?
결국 HTTPS의 본질은 TLS Handshake를 통해 서로의 랜덤값과 공개키를 주고받으며 데이터 암호화에 사용할 Session Key(대칭키) 를 만들어내는 것이다. 이 과정의 출발점이 되는 공개키가 어떻게 만들어지고 교환 될까?
클라이언트의 공개키는 어떻게 만들어지는걸까?
우리가 따로 건드리지 않아도 된다.
“명시적으로” 브라우저에게 뭘 만들라고 말하지 않아도,
브라우저 안의 TLS 엔진(OpenSSL, BoringSSL 등)이 자동으로 생성한다.
브라우저도 TLS 연결을 시작할 때 자신만의 임시 공개키를 자동으로 생성해서
ClientHello 메시지 안에 이 공개키(client_keyshare)를 넣어 보낸다.
서버의 공개키는 어떻게 만들어지는걸까?
여긴 우리가 처리하는 공간이다.
HTTPS를 사용하려면 서버는 미리 인증서 발급기관 (Certificate Authority) 에서 발급받은 인증서를 가지고 있어야한다. 브라우저는 전 세계적으로 공인된 CA 목록을 Root Store 에 내장하고 있어서, 인증서 검증에 유효한 CA인지도 확인할 수 있다.
인증서는 보통 이렇게 생겼다.
Subject: CN=*.example.com
Issuer: Amazon RSA 2048 CA
Valid: 2024-06-01 ~ 2025-06-01
Public Key: ...
Signature: (CA의 개인키로 서명)
우리가 서버를 설정할 때 ACM(AWS Certificate Manager)이나 Nginx 설정으로 미리 만들어 두게 된다.
즉, 서버의 공개키는 미리 존재하고, 서버가 브라우저에게 보내주는 것.
AWS의 ACM으로 인증서 관리하기
인증서를 보면 알 수 있듯, HTTPS는 도메인 단위로 신뢰를 보장합니다. (서브도메인이 함께 씀)
ACM은 인증서 관리를 쉽게해주는 서비스로 없다면 매우 피곤해진다.
아래는 AWS ACM을 이용해서 인증서를 발급하는 흐름이다.
- ACM 콘솔에서 새 인증서 발급 요청을 한다.
- 이때 원하는 도메인을 입력한다.
- Route53에 ACM이 요구하는 CNAME 추가(for 소유권 증명)
- ACM이 요청하는대로 CNAME 레코드를 생성한다.
- CA가 검증을 완료하면 ACM에 새로운 인증서가 발급된다.
- 인증서를 붙일 엔드포인트에 인증서를 연결한다
- CDN이라면, CloudFront의 Alternate Domain Names에 ACM을 추가한다.
- ALB라면, 443 포트에 대한 인바운드(요청)을 추가 → ACM인증서를 선택 → TargetGroup을 연결
- Route53에서 해당 도메인의 Alias(AWS)로 엔드포인트의 AWS주소를 추가한다.
ACM이 없다면,
- CA 사이트로 직접 가서 발급받아야 하며, 발급받은 파일들을 EC2 등에 직접 설치해야되는 번거로움
- 유효기간 (90일 ~ 1일)이 지나면 갱신도 직접 다시해야한다.
- DNS의 CNAME이 바뀌지 않는다면, ACM은 자동으로 인증서를 갱신해준다.
왜 ACM에서는 CNAME으로 소유권을 증명하나?
CNAME은 DNS에서 ‘하나의 도메인을 다른 도메인으로 가리키는(별명 붙이는)’ 표준 레코드 타입
docs.example.com → CNAME → ghs.googlehosted.com
cdn.example.com → CNAME → d123.cloudfront.net
docs.example.com에 접근하면 DNS는 “이건ghs.googlehosted.com으로 연결돼 있어” 하고 알려줌- 이렇게 도메인 이름끼리 연결하는 게 CNAME이다.
이것이 원래 CNAME의 용도지만, AWS ACM은 “이 도메인의 DNS에 내가 지정한 CNAME을 하나 추가하면,네가 그 DNS를 제어하고 있다는 걸로 인정하고 관리해줄게.”라고 말하는 것이다. 즉 “도메인 소유권을 증명하는 용도” 로 CNAME 레코드를 “활용”한다.
참고 : AWS의 A레코드(DNS레코드)도 아니고 Alias 레코드는 뭐지?
example.com → 192.0.2.10네트워크에서 A 레코드는 IPv4와 도메인을 연결하는 기본적인 레코드다. 유저가 example.com을 하면 DNS서비스를 통해 실제 엔드포인트 주소(IP)를 가져오는데 쓰인다.
Alias 레코드는 AWS 리소스 전용의 특수한 A레코드로, 일반적인 A레코드의 기능도 하지만, AWS 인스턴스가 다시 배포될때 내부 IP가 바뀌는데, 이걸 감지해서 자동 갱신되도록 만드는 기능까지 추가되어 있는 것
프론트엔드 개발자에게 HTTPS가 중요한 이유
1. 교차 출처 요청에선 CORS 정책보다 HTTPS가 우선
프론트엔드에서 API 요청을 보낼 때, 브라우저는 항상 “이 리소스를 신뢰할 수 있는가?”를 검사한다.
이때, 교차 출처 요청(Cross-Origin Request) 의 경우, Access-Control-* 헤더(CORS 정책)보다 HTTPS 보안 연결이 우선이다.
- HTTPS에서 HTTP 요청의 경우 “Mixed Content”로 감지되어 브라우저가 자동으로 막는다.
- 반대의 경우 HTTP 페이지에서 HTTPS 리소스로 요청을 보내도 브라우저가 차단한다.
이건 네트워크나 서버 문제가 아니라, 브라우저가 “보안 수준이 낮은 곳에서 높은 곳으로 접근”을 허용하지 않기 때문.
HTTPS 도메인 간 요청의 경우(교차 출처인 경우), 응답 헤더에 반드시
Access-Control-Allow-Origin: https://your-frontend.com이 포함되어야만 브라우저가 요청을 허용합니다.
2. 쿠키 전송 제한
보안이 강화된 브라우저에서는 쿠키가 다음과 같은 규칙으로 동작한다
Secure옵션이 붙은 쿠키는 HTTPS 연결에서만 전송SameSite=None쿠키도 HTTPS가 아닐 경우 무조건 차단
즉, 로그인 세션이나 토큰을 쿠키로 관리하는 서비스가
HTTPS 환경이 아니면 로그인이 아예 동작하지 않거나 세션이 유지되지 않는다.
3. Service Worker / PWA
오프라인 캐싱, 푸시 알림, 백그라운드 동작 같은 Service Worker 기능은 HTTPS 환경에서만 등록(register) 가능하다.
이건 브라우저 보안 모델 때문인데, Service Worker는 네트워크를 가로채 캐싱을 조작할 수 있는 만큼 HTTP 환경에서는 보안상 위험하다고 판단되어 금지되어 있다.
4. SEO / 브라우저 경고
Google, Naver 등 주요 검색엔진은 HTTP 사이트를 “보안 취약” 사이트로 분류한다.
또한 최신 브라우저(Chrome, Safari, Edge)는
HTTP 페이지에 접속 시 주소창에 Not Secure 경고를 띄운다,
이건 단순히 시각적인 경고를 넘어, SEO 점수 하락, 사용자의 이탈률 증가, HTTPS 페이지에서 HTTP 자원이 포함될 경우(Mixed Content) 자동 차단 같은 실질적인 UX 악영향으로 이어진다.
5. AWS 리소스 (CloudFront, Amplify, API Gateway)
AWS의 대부분의 웹 엔드포인트 서비스는 HTTPS만 허용하도록 설계되어 있다.
대표적으로 CloudFront, Amplify, API Gateway는 모두 ACM(AWS Certificate Manager) 인증서 기반 HTTPS 엔드포인트를 기본으로 제공한다. 즉, AWS에서 서비스를 배포하는 시점부터 HTTPS 환경을 필수로 고려해야 한다.
HTTPS 문제를 만났을 때 체크리스트
- 인증서 확인
- 브라우저 주소창의 🔒 아이콘 클릭 → “인증서 보기”
- 도메인(
CN)이 실제 서비스 도메인과 일치하는가? - 유효기간이 만료되지 않았는가?
- 인증서 발급자가 신뢰할 수 있는 CA인가? (예: Amazon, Let's Encrypt 등)
- DNS 설정 점검
- Route53 등에서 A(Alias) 또는 CNAME이 올바른 엔드포인트(CloudFront/ALB)를 가리키는가?
www.example.com과example.com을 혼용하지 않았는가?- CloudFront라면 ACM 인증서가 us-east-1 리전에 존재하는지 확인
- Mixed Content 차단 확인
- HTTPS 페이지 안에서 HTTP 이미지, JS, CSS를 불러오는 리소스가 있는가?
→ 개발자 도구 Console에 “Mixed Content” 경고로 표시됨
→ 모든 외부 리소스 URL을
https://로 교체
- HTTPS 페이지 안에서 HTTP 이미지, JS, CSS를 불러오는 리소스가 있는가?
→ 개발자 도구 Console에 “Mixed Content” 경고로 표시됨
→ 모든 외부 리소스 URL을
- 브라우저 캐시 / DNS 캐시 초기화
- 캐시된 HSTS 정책이나 이전 인증서가 남아 있을 수 있음
- Chrome:
chrome://net-internals/#hsts→ 삭제 후 재접속